﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace cc2530.Lib.contiki
{



    class Echorequest:IPv6ICMPHeader{

        public UInt16 Identifier { 
            get{UInt16 i = message[0];i<<=8;i+=message[1];return i;  }
            set{message[0] = (byte)(value>>8);message[1]=(byte)value;}
        }

        public UInt16 SequenceNumber {           
            get{UInt16 i = message[2];i<<=8;i+=message[3];return i;  }
            set{message[2] = (byte)(value>>8);message[3]=(byte)value;} 
        }

        public byte[] Data{
            get{
                byte[] n = new byte[message.Length-4];
                Array.Copy(message, 4, n, 0, n.Length);
                return n;
            }
            set {

                byte[] n = new byte[value.Length + 4];
                Array.Copy(value, 0, n, 4, value.Length);
                Array.Copy(message, 0, n, 0, 4);
                message = n;
            }

        }

        

        public Echorequest(){}
        public Echorequest(byte[] _d,int offset,int len):base(_d,offset,len)
        {}

}

    class Echoreply : IPv6ICMPHeader {

        public UInt16 Identifier { 
            get{UInt16 i = message[0];i<<=8;i+=message[1];return i;  }
            set{message[0] = (byte)(value>>8);message[1]=(byte)value;}
        }

        public UInt16 SequenceNumber {           
            get{UInt16 i = message[2];i<<=8;i+=message[3];return i;  }
            set{message[2] = (byte)(value>>8);message[3]=(byte)value;} 
        }

        public byte[] Data{
            get{
                byte[] n = new byte[message.Length-4];
                Array.Copy(message, 4, n, 0, n.Length);
                return n;
            }
            set {

                byte[] n = new byte[value.Length + 4];
                Array.Copy(value, 0, n, 4, value.Length);
                Array.Copy(message, 0, n, 0, 4);
                message = n;
            }

        }

        

        public Echoreply(){}
        public Echoreply(byte[] _d, int offset, int len)
        {
            message = new byte[len];
            Array.Copy(_d, offset, message, 0, message.Length);
        }

}
    /// <summary>
    /// 下一首头类型
    /// </summary>
   public enum IPv6NextHeaderType { 
        
            //        关键字		十进制		协议	引用		十六进制
            HOPOPT	=	0	,//	IPv6逐跳选项	RFC 2460		0x00
            ICMP	=	1	,//	互联网控制消息协议	RFC 792		0x01
            IGMP	=	2	,//	因特网组管理协议	RFC 1112	,//	0x02
            GGP	=	3	,//	网关对网关协议	RFC 823	,//	0x03
            IPv4	=	4	,//	IPv4 (封装)	RFC 791	,//	0x04
            ST	=	5	,//	因特网流协议	RFC 1190, RFC 1819	,//	0x05
            TCP	=	6	,//	传输控制协议	RFC 793	,//	0x06
            CBT	=	7	,//	有核树组播路由协议	RFC 2189	,//	0x07
            EGP	=	8	,//	外部网关协议	RFC 888	,//	0x08
            IGP	=	9	,//	内部网关协议（任意私有内部网关（用于思科的IGRP））		,//	0x09
            BBN_RCC_MON	=	10	,//	BBN RCC 监视		,//	0x0A
            NVP_II	=	11	,//	网络语音协议	RFC 741	,//	0x0B
            PUP	=	12	,//	Xerox PUP		,//	0x0C
            ARGUS	=	13	,//	ARGUS		,//	0x0D
            EMCON	=	14	,//	EMCON		,//	0x0E
            XNET	=	15	,//	Cross Net Debugger	IEN 158	,//	0x0F
            CHAOS	=	16	,//	Chaos		,//	0x10
            UDP	=	17	,//	用户数据报协议	RFC 768	,//	0x11
            MUX	=	18	,//	Multiplexing	IEN 90	,//	0x12
            DCN_MEAS	=	19	,//	DCN Measurement Subsystems		,//	0x13
            HMP	=	20	,//	Host Monitoring Protocol	RFC 869	,//	0x14
            PRM	=	21	,//	Packet Radio Measurement		,//	0x15
            XNS_IDP	=	22	,//	XEROX NS IDP		,//	0x16
            TRUNK_1	=	23	,//	Trunk-1		,//	0x17
            TRUNK_2	=	24	,//	Trunk-2		,//	0x18
            LEAF_1	=	25	,//	Leaf-1		,//	0x19
            LEAF_2	=	26	,//	Leaf-2		,//	0x1A
            RDP	=	27	,//	Reliable Datagram Protocol	RFC 908	,//	0x1B
            IRTP	=	28	,//	Internet Reliable Transaction Protocol	RFC 938	,//	0x1C
            ISO_TP4	=	29	,//	ISO Transport Protocol Class 4	RFC 905	,//	0x1D
            NETBLT	=	30	,//	Bulk Data Transfer Protocol	RFC 998	,//	0x1E
            MFE_NSP	=	31	,//	MFE Network Services Protocol		,//	0x1F
            MERIT_INP	=	32	,//	MERIT Internodal Protocol		,//	0x20
            DCCP	=	33	,//	Datagram Congestion Control Protocol	RFC 4340	,//	0x21
            _3PC	=	34	,//	Third Party Connect Protocol		,//	0x22
            IDPR	=	35	,//	Inter-Domain Policy Routing Protocol	RFC 1479	,//	0x23
            XTP	=	36	,//	Xpress Transport Protocol		,//	0x24
            DDP	=	37	,//	Datagram Delivery Protocol		,//	0x25
            IDPR_CMTP	=	38	,//	IDPR Control Message Transport Protocol		,//	0x26
            TPpluspuls	=	39	,//	TP++ Transport Protocol		,//	0x27
            IL	=	40	,//	IL Transport Protocol		,//	0x28
            IPv6	=	41	,//	IPv6 Encapsulation	RFC 2473	,//	0x29
            SDRP	=	42	,//	Source Demand Routing Protocol	RFC 1940	,//	0x2A
            IPv6_Route	=	43	,//	Routing Header for IPv6	RFC 2460	,//	0x2B
            IPv6_Frag	=	44	,//	Fragment Header for IPv6	RFC 2460	,//	0x2C
            IDRP	=	45	,//	Inter-Domain Routing Protocol		,//	0x2D
            RSVP	=	46	,//	Resource Reservation Protocol	RFC 2205	,//	0x2E
            GRE	=	47	,//	Generic Routing Encapsulation	RFC 2784, RFC 2890	,//	0x2F
            MHRP	=	48	,//	Mobile Host Routing Protocol		,//	0x30
            BNA	=	49	,//	BNA		,//	0x31
            ESP	=	50	,//	Encapsulating Security Payload	RFC 4303	,//	0x32
            AH	=	51	,//	Authentication Header	RFC 4302	,//	0x33
            I_NLSP	=	52	,//	Integrated Net Layer Security Protocol	TUBA	,//	0x34
            SWIPE	=	53	,//	SwIPe	IP with Encryption	,//	0x35
            NARP	=	54	,//	NBMA Address Resolution Protocol	RFC 1735	,//	0x36
            MOBILE	=	55	,//	IP Mobility (Min Encap)	RFC 2004	,//	0x37
            TLSP	=	56	,//	Transport Layer Security Protocol (using Kryptonet key management)		,//	0x38
            SKIP	=	57	,//	Simple Key-Management for Internet Protocol	RFC 2356	,//	0x39
            IPv6_ICMP	=	58	,//	ICMP for IPv6	RFC 4443, RFC 4884	,//	0x3A
            IPv6_NoNxt	=	59	,//	No Next Header for IPv6	RFC 2460	,//	0x3B
            IPv6_Opts	=	60	,//	Destination Options for IPv6	RFC 2460	,//	0x3C
	        AHIP    =	61	,//	Any host internal protocol		,//	0x3D
            CFTP	=	62	,//	CFTP		,//	0x3E
	        ALN    =	63	,//	Any local network		,//	0x3F
            SAT_EXPAK	=	64	,//	SATNET and Backroom EXPAK		,//	0x40
            KRYPTOLAN	=	65	,//	Kryptolan		,//	0x41
            RVD	=	66	,//	MIT Remote Virtual Disk Protocol		,//	0x42
            IPPC	=	67	,//	Internet Pluribus Packet Core		,//	0x43
	        ADFS    =	68	,//	Any distributed file system		,//	0x44
            SAT_MON	=	69	,//	SATNET Monitoring		,//	0x45
            VISA	=	70	,//	VISA Protocol		,//	0x46
            IPCV	=	71	,//	Internet Packet Core Utility		,//	0x47
            CPNX	=	72	,//	Computer Protocol Network Executive		,//	0x48
            CPHB	=	73	,//	Computer Protocol Heart Beat		,//	0x49
            WSN	=	74	,//	Wang Span Network		,//	0x4A
            PVP	=	75	,//	Packet Video Protocol		,//	0x4B
            BR_SAT_MON	=	76	,//	Backroom SATNET Monitoring		,//	0x4C
            SUN_ND	=	77	,//	SUN ND PROTOCOL-Temporary		,//	0x4D
            WB_MON	=	78	,//	WIDEBAND Monitoring		,//	0x4E
            WB_EXPAK	=	79	,//	WIDEBAND EXPAK		,//	0x4F
            ISO_IP	=	80	,//	International Organization for Standardization Internet Protocol		,//	0x50
            VMTP	=	81	,//	Versatile Message Transaction Protocol	RFC 1045	,//	0x51
            SECURE_VMTP	=	82	,//	Secure Versatile Message Transaction Protocol	RFC 1045	,//	0x52
            VINES	=	83	,//	VINES		,//	0x53
            TTP	=	84	,//	TTP		,//	0x54
            IPTM	=	84	,//	Internet Protocol Traffic Manager		,//	0x54
            NSFNET_IGP	=	85	,//	NSFNET-IGP		,//	0x55
            DGP	=	86	,//	Dissimilar Gateway Protocol		,//	0x56
            TCF	=	87	,//	TCF		,//	0x57
            EIGRP	=	88	,//	EIGRP		,//	0x58
            OSPF	=	89	,//	Open Shortest Path First	RFC 1583	,//	0x59
            Sprite_RPC	=	90	,//	Sprite RPC Protocol		,//	0x5A
            LARP	=	91	,//	Locus Address Resolution Protocol		,//	0x5B
            MTP	=	92	,//	Multicast Transport Protocol		,//	0x5C
            AXDot25	=	93	,//	AX.25		,//	0x5D
            IPIP	=	94	,//	IP-within-IP Encapsulation Protocol	RFC 2003	,//	0x5E
            MICP	=	95	,//	Mobile Internetworking Control Protocol		,//	0x5F
            SCC_SP	=	96	,//	Semaphore Communications Sec. Pro		,//	0x60
            ETHERIP	=	97	,//	Ethernet-within-IP Encapsulation	RFC 3378	,//	0x61
            ENCAP	=	98	,//	Encapsulation Header	RFC 1241	,//	0x62
	        APES    =	99	,//	Any private encryption scheme		,//	0x63
            GMTP	=	100	,//	GMTP		,//	0x64
            IFMP	=	101	,//	Ipsilon Flow Management Protocol		,//	0x65
            PNNI	=	102	,//	PNNI over IP		,//	0x66
            PIM	=	103	,//	Protocol Independent Multicast		,//	0x67
            ARIS	=	104	,//	IBM's ARIS (Aggregate Route IP Switching) Protocol		,//	0x68
            SCPS	=	105	,//	SCPS (Space Communications Protocol Standards)	SCPS-TP[1]	,//	0x69
            QNX	=	106	,//	QNX		,//	0x6A
            AN	=	107	,//	Active Networks		,//	0x6B
            IPComp	=	108	,//	IP Payload Compression Protocol	RFC 3173	,//	0x6C
            SNP	=	109	,//	Sitara Networks Protocol		,//	0x6D
            Compaq_Peer	=	110	,//	Compaq Peer Protocol		,//	0x6E
            IPX_in_IP	=	111	,//	IPX in IP		,//	0x6F
            VRRP	=	112	,//	Virtual Router Redundancy Protocol, Common Address Redundancy Protocol (not IANAassigned)	VRRP:RFC 3768	,//	0x70
            PGM	=	113	,//	PGM Reliable Transport Protocol	RFC 3208	,//	0x71
	        A0HP    =	114	,//	Any 0-hop protocol		,//	0x72
            L2TP	=	115	,//	Layer Two Tunneling Protocol Version 3	RFC 3931	,//	0x73
            DDX	=	116	,//	D-II Data Exchange (DDX)		,//	0x74
            IATP	=	117	,//	Interactive Agent Transfer Protocol		,//	0x75
            STP	=	118	,//	Schedule Transfer Protocol		,//	0x76
            SRP	=	119	,//	SpectraLink Radio Protocol		,//	0x77
            UTI	=	120	,//	Universal Transport Interface Protocol		,//	0x78
            SMP	=	121	,//	Simple Message Protocol		,//	0x79
            SM	=	122	,//	Simple Multicast Protocol	draft-perlman-simple-multicast-03	,//	0x7A
            PTP	=	123	,//	Performance Transparency Protocol		,//	0x7B
            IS_IS_over_IPv4	=	124	,//	Intermediate System to Intermediate System (IS-IS) Protocol over IPv4	RFC 1142 and RFC 1195	,//	0x7C
            FIRE	=	125	,//	Flexible Intra-AS Routing Environment		,//	0x7D
            CRTP	=	126	,//	Combat Radio Transport Protocol		,//	0x7E
            CRUDP	=	127	,//	Combat Radio User Datagram		,//	0x7F
            SSCOPMCE	=	128	,//	Service-Specific Connection-Oriented Protocol in a Multilink and Connectionless Environment	ITU-T Q.2111 (1999)	,//	0x80
            IPLT	=	129	,//			,//	0x81
            SPS	=	130	,//	Secure Packet Shield		,//	0x82
            PIPE	=	131	,//	Private IP Encapsulation within IP	Expired I-D draft-petri-mobileip-pipe-00.txt	,//	0x83
            SCTP	=	132	,//	Stream Control Transmission Protocol		,//	0x84
            FC	=	133	,//	Fibre Channel		,//	0x85
            RSVP_E2E_IGNORE	=	134	,//	Reservation Protocol (RSVP) End-to-End Ignore	RFC 3175	,//	0x86
            Mobility_Header	=	135	,//	Mobility Extension Header for IPv6	RFC 6275	,//	0x87
            UDPLite	=	136	,//	Lightweight User Datagram Protocol	RFC 3828	,//	0x88
            MPLS_in_IP	=	137	,//	Multiprotocol Label Switching Encapsulated in IP	RFC 4023	,//	0x89
            manet	=	138	,//	MANET Protocols	RFC 5498	,//	0x8A
            HIP	=	139	,//	Host Identity Protocol	RFC 5201	,//	0x8B
            Shim6	=	140	,//	Site Multihoming by IPv6 Intermediation	RFC 5533	,//	0x8C
            WESP	=	141	,//	Wrapped Encapsulating Security Payload	RFC 5840	,//	0x8D
            ROHC	=	142	,//	Robust Header Compression	RFC 5856	,//	0x8E
            UNASSIGNED	=	143-252	,//			,//	0x8F-0xFC
           // Use for experimentation and testing	=	253-254	,//		RFC 3692	,//	0xFD-0xFE
            Reserved   =	255	,//			,//	0xFF

    }



    /// <summary>
    /// IPv6 的数据 包头
    /// </summary>
    public class IPv6Header {

        /*
         * *    ipv6 header  ----MSB
               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
               |Version| Traffic Class |           Flow Label                  |
               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
               |         Payload Length        |  Next Header  |   Hop Limit   |
               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
               |                                                               |
               +                                                               +
               |                                                               |
               +                         Source Address                        +
               |                                                               |
               +                                                               +
               |                                                               |
               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
               |                                                               |
               +                                                               +
               |                                                               |
               +                      Destination Address                      +
               |                                                               |
               +                                                               +
               |                                                               |
               +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
         */
        /// <summary>
        /// 版本
        /// </summary>
        public byte Version {
            get {
               return  GetHigh4bits(_data[0]);
            }
            set {
                SetHigh4bits(_data, 0, value);
            }
        }
        /// <summary>
        /// 类, tos fragment
        /// </summary>
        public byte TrafficClass { 
            set {
                SetLow4bits(_data, 0, (byte)(value>>4));
                SetHigh4bits(_data,1,value);
            }
            get {
                return (byte)((byte)(_data[0] << 4) + (byte)(_data[1] >> 4));
            }
        }
        /// <summary>
        /// 流标 20bits
        /// </summary>
        public UInt32 FlowLabel {
            get { UInt32 dd = (UInt32)(_data[1] & 0x0F); dd <<= 8; dd += _data[2]; dd <<= 8; dd += _data[3]; return dd; }
            set { SetLow4bits(_data, 1, (byte)(value >> 8)); _data[2] = (byte)(value >> 8); _data[3] = (byte)(value); }
        }
        /// <summary>
        /// 数据长度
        /// </summary>
        public UInt16 PayloadLength { 
            set { _data[4] = (byte)(value >> 8); _data[5] = (byte)(value); }
            get { UInt16 d = _data[4]; d <<= 8; d += _data[5]; return d; }                
        }
        /// <summary>
        /// 下一头
        /// </summary>
        public IPv6NextHeaderType NextHeader { get { return (IPv6NextHeaderType)_data[6]; } set { _data[6] = (byte)(value); } }
        /// <summary>
        /// 跳数
        /// </summary>
        public byte HopLimit { get { return (byte)_data[7]; } set { _data[7] = (byte)(value); } }
        /// <summary>
        /// 源地址
        /// </summary>
        public byte[] SourceAddress {
            get {
                byte[] s = new byte[16];
                Array.Copy(_data, 8, s, 0, 16); return s;
            }
            set {
                Array.Copy(value, 0, _data, 8, 16);
            }
        }
        /// <summary>
        /// 目标地址
        /// </summary>
        public byte[] DestnationAddress
        {
            get
            {
                byte[] s = new byte[16];
                Array.Copy(_data, 24, s, 0, 16); return s;
            }
            set
            {
                Array.Copy(value, 0, _data, 24, 16);
            }
        }

        public byte[] HeaderData { get { return _data; } }

        private byte[] _data = new byte[HeaderSize];

        /// <summary>
        /// 从ip 数据包中创建 ipv6 header
        /// </summary>
        /// <param name="ipdata"></param>
        public IPv6Header(byte[] ipdata)
        {
            Array.Copy(ipdata, _data, HeaderSize);
        }

        public IPv6Header() { }


        public static IPv6Header Parse(byte[] LLdata, int offset)
        {
            try
            {
                byte[] ipdata = new byte[HeaderSize];
                Array.Copy(LLdata, offset, ipdata,0, HeaderSize);
                return new IPv6Header(ipdata);
            }
            catch {
                return null;
            }
        }
        /// <summary>
        /// 头长度
        /// </summary>
        public static int HeaderSize { get { return 40; } }


        private void SetLow4bits(byte[] d, int offset, byte v) { d[offset] &= 0xF0; d[offset] += (byte)(v & 0x0F); }
        private void SetHigh4bits(byte[] d, int offset, byte v) { d[offset] &= 0x0F; v <<= 4; d[offset] += v; }
        private byte GetLow4bits(byte d) { return (byte)(d & 0x0F); }
        private byte GetHigh4bits(byte d) { return (byte)(d >> 4); }
    }

    public enum ICMPv6Type {
        //ICMPv6 Error Messages
        DestinationUnreachable = 1,
        PacketTooBig = 2,
        TimeExceeded = 3,
        ParamenterProblem = 4,

                //ICMPv6 Informational Messages
        Echo_Request	=	128	,//  value =	0	
        Echo_Reply	=	129	,//  value =	0	
        Multicast_Listener_Query	=	130	,//  value =	0	There are two subtypes of Multicast Listener Query messages:
	                                        //=		,//  value =		General Query, used to learn which multicast addresses have listeners on an attached link.
	                                        //=		,//  value =		Multicast-Address-Specific Query, used to learn if a particular multicast address has any listeners on an attached link.
	                                        //=		,//  value =		These two subtypes are differentiated by the contents of the Multicast Address field, as described in section 3.6 of RFC 2710
        Multicast_Listener_Report	=	131	,//  value =	0	
        Multicast_Listener_Done	=	132	    ,//  value =	0	
        Router_Solicitation_NDP	=	133	,   //  value =	0	
        Router_Advertisement_NDP	=	134	,//  value =	0	
        Neighbor_Solicitation_NDP	=	135	,//  value =	0	
        Neighbor_Advertisement_NDP	=	136	,//__value_=	0	
        Redirect_Message_NDP	=	137	,   //__value_=	0
	
        Router_Renumbering	=	138	,       //__value_=	0	Router_Renumbering_Command
	                                        //=		,//__value_=	1	Router_Renumbering_Result
	                                        //=		,//__value_=	255	Sequence_Number_Reset
        ICMP_Node_Information_Query	=	139	,
                                            //__value_=	0	The_Data_field_contains_an_IPv6_address_which_is_the_Subject_of_this_Query.
	                                        //=		,//__value_=	1	The_Data_field_contains_a_name_which_is_the_Subject_of_this_Query,_or_is_empty,_as_in_the_case_of_a_NOOP.
	                                        //=		,//__value_=	2	The_Data_field_contains_an_IPv4_address_which_is_the_Subject_of_this_Query.
       
        ICMP_Node_Information_Response	=	140	,
            //__value_=	0	A_successful_reply._The_Reply_Data_field_may_or_may_not_be_empty.
	        //=		,//__value_=	1	The_Responder_refuses_to_supply_the_answer._The_Reply_Data_field_will_be_empty.
	        //=		,//__value_=	2	The_Qtype_of_the_Query_is_unknown_to_the_Responder._The_Reply_Data_field_will_be_empty.
        
        Inverse_Neighbor_Discovery_Solicitation_Message	=	141	,//__value_=	0	
        Inverse_Neighbor_Discovery_Advertisement_Message	=	142	,//__value_=	0	
        Multicast_Listener_Discovery_MLDv2	=	143	,//__value_=	               _reports_(RFC_3810)	
        Home_Agent_Address_Discovery_Request_Message	=	144	,//__value_=	0	
        Home_Agent_Address_Discovery_Reply_Message	=	145	,//__value_=	0	
        Mobile_Prefix_Solicitation	=	146	,//__value_=	0	
        Mobile_Prefix_Advertisement	=	147	,//__value_=	0	
        Certification_Path_Solicitation_SEND	=	148	,//__value_=		
        Certification_Path_Advertisement_SEND	=	149	,//__value_=		
        Multicast_Router_Advertisement_MRD	=	151	,//__value_=		
        Multicast_Router_Solicitation_MRD	=	152	,//__value_=		
        Multicast_Router_Termination_MRD	=	153	,//__value_=		
        RPL_Control_Message	=	155	,//__value_=		
        Private_experimentation	=	200	,//__value_=		
        Private_experimentation2	=	201	,//__value_=		
        Reserved_for_expansion_of_ICMPv6_informational_messages	=	255	,//__value_=		
    }


    public class IPv6ICMPPseudoHeader
    {
        #region infomation
        /*
                              
        *    伪头用来计算checksum
        *    ICMPv6 pseudo-header
                                Bit offset	0 - 7	8–15	16–23	24–31
                                            0	     Source address
                                            32
                                            64
                                            96
                                            128	     Destination address
                                            160
                                            192
                                            224
                                            256	      ICMPv6 length
                                            288	     Zeros	Next header            
         */
        #endregion

        public byte[] SourceAddress = new byte[16];
        public byte[] DestationAddress = new byte[16];
        public UInt16 PayloadLen;
        public IPv6NextHeaderType next;
        public byte[] icmpv6data;

        /// <summary>
        /// 计算icmpv6检验和
        /// </summary>
        /// <returns></returns>
        public UInt16 ToCheckSum() {

            /*
             Message checksum[edit]
                ICMPv6 provides a minimal level of message integrity verification by the inclusion of a 16-bit checksum in its header. 
             * The checksum is calculated starting with a pseudo-header of IPv6 header fields according to the IPv6 standard,[3] 
             * which consists of the source and destination addresses, the packet length and the next header field, 
             * the latter of which is set to the value 58. Following this pseudo header, 
             * the checksum is continued with the ICMPv6 message in which the checksum is initially set to zero. 
             * The checksum computation is performed according to Internet protocol standards using 16-bit ones' complement summation, 
             * followed by complementing the checksum itself and inserting it into the checksum field.[4] 
             * Note that this differs from the way it is calculated for IPv4 in ICMP, 
             * but is similar to the calculation done in TCP.
             */
            UInt16 sum = 0;

            sum = PayloadLen;
            sum += (UInt16)next;
            sum = Ulitily.ShareClass.CheckSum16(sum, SourceAddress, 16);
            sum = Ulitily.ShareClass.CheckSum16(sum, DestationAddress, 16);
            icmpv6data[2] = 0; icmpv6data[3] = 0;
            sum = Ulitily.ShareClass.CheckSum16(sum, icmpv6data, icmpv6data.Length);

            return (UInt16)~((sum == 0) ? (UInt16)0xffff : sum);
        }
    }
    public class IPv6ICMPHeader {

            #region information

                    /*
     
                        ICMPv6 封包
                        Bit offset	0–7	8–15	16–31
                            0   	类型	代码	校验和
                            32	    消息体
                     */


                    /*
                     *    伪头用来计算checksum
                     *    ICMPv6 pseudo-header
                                                Bit offset	0 - 7	8–15	16–23	24–31
                                                            0	     Source address
                                                            32
                                                            64
                                                            96
                                                            128	     Destination address
                                                            160
                                                            192
                                                            224
                                                            256	      ICMPv6 length
                                                            288	     Zeros	Next header
                     */


            #endregion


        public ICMPv6Type type { get { return (ICMPv6Type)_data[0]; } set { _data[0] = (byte)value; } }

        public byte code { get { return _data[1]; } set { _data[1] = value; } }



        public UInt16 checksum
        {
            get { UInt16 dd = _data[2]; dd <<= 8; dd += _data[3]; return dd; }
            set { _data[2] = (byte)(value >> 8); _data[3] = (byte)(value); }
        }

        public byte[] icmpdata {
            get { return _data; }
            set { _data = value; }
        }
        private byte[] _data;

        /// <summary>
        /// 信息区,依据各种 类型不同
        /// </summary>
        public byte[] message {
            get { byte[] dd = new byte[_data.Length - 4]; Array.Copy(_data,4,dd,0,dd.Length); return dd; }
            set {
                byte[] _m = new byte[value.Length + 4];
                Array.Copy(_data, 0, _m, 0, 4);
                Array.Copy(value, 0, _m, 4, value.Length);
                _data = _m;
            }
        }

        public IPv6ICMPHeader() { }

        public IPv6ICMPHeader(byte[] data,int offset){
            _data = new byte[data.Length - offset];
            Array.Copy(data, offset, _data, 0, _data.Length);
        }

        public IPv6ICMPHeader(byte[] data, int offset, int len)
        {
            _data = new byte[len];
            Array.Copy(data, offset, _data, 0, len);
        }


        #region static 函数 
        /// <summary>
        /// 通过报文创建 header
        /// </summary>
        /// <param name="icmpv6data"></param>
        /// <param name="offset"></param>
        /// <returns></returns>
        public static IPv6ICMPHeader Parse(byte[] icmpv6data, int offset)
        {
            return new IPv6ICMPHeader(icmpv6data, offset);
        }



        public static UInt64 BitOffset(int offset) { return (UInt64)1 << offset; }
        public static UInt64 RBitOffset(int offset) { return (UInt64)~((UInt64)1 << offset);}

        /// <summary>
        /// 设置 data[] 的第 n 位 [0].MSB ,offset = 0
        /// </summary>
        /// <param name="data"></param>
        /// <param name="offset"></param>
        /// <param name="value"></param>
        public static void   BitSet(byte[] data, int offset,byte value) {
            if (value > 0) { data[offset / 8] |= (byte)BitOffset(7 - offset % 8); }
            else { data[offset/8] &= (byte)RBitOffset(7-offset%8); }
        }

        public static byte BitGet(byte[] data, int offset) { 
            if((byte)(data[offset/8]|(byte)BitOffset(7-offset%8)) >0)return 1;
            else return 0;
        }

        public static void UInt16Set(byte[] data, int offset, UInt16 v) {
            data[offset] = (byte)(v >> 8);
            data[offset + 1] = (byte)(v & 0xFF);
        }
        public static UInt16 UInt16Get(byte[] data, int offset)
        {
            UInt16 v = data[offset]; v <<= 8; v += data[offset + 1]; return v;
        }

        public static void UInt32Set(byte[] data, int offset, UInt32 v)
        {
            data[offset] = (byte)(v >> 24);
            data[offset + 1] = (byte)(v>>16);
            data[offset+2] = (byte)(v>>8);
            data[offset +3] = (byte)(v);
        }
        public static UInt32 UInt32Get(byte[] data, int offset)
        {
            UInt32 v=0;
            v += data[offset++]; v <<= 8; 
            v += data[offset++]; v <<= 8;
            v += data[offset++]; v <<= 8;
            v += data[offset++];
            return v;
        }

        #endregion
   
    
    }


    /// <summary>
    /// 选项类型
    /// </summary>
    public enum IPv6ICMPOptionType { 
        LinkSourceAddress = 1,
        LinkDestationAddress = 2,
        Prefix = 3,
        Redirect = 4,
        MTU = 5,
    }

    /// <summary>
    /// icmp v6 的 选项字节 类
    /// </summary>
    public class IPv6ICMPOption {

        /// <summary>
        /// option 类型
        /// </summary>
        public IPv6ICMPOptionType type { get { return (IPv6ICMPOptionType)_data[0]; } set { _data[0] = (byte)value; } }

        /// <summary>
        /// option长度，以8字节为单位
        /// </summary>
        public byte optionLen { get { return _data[1]; } set { _data[1] = value; } }


        /// <summary>
        /// all option data (include type option len)
        /// </summary>
        public byte[] data {
            set { _data = value; }
            get { return _data; }
        }


        /// <summary>
        /// 选择数据，不包括(type,len)
        /// </summary>
        public byte[] optionData {
            get {
                byte[] _d = new byte[_data.Length - 2];
                Array.Copy(_data, 2, _d, 0, _d.Length);
                return _d;
            }
        }

        private byte[] _data;

        public IPv6ICMPOption(byte[] _option,int offset)
        {
            _data = new byte[_option.Length - offset];
            Array.Copy(_option, offset, _data, 0, _data.Length);
        }

    }

    /// <summary>
    /// 路由请求      icmp type == 133
    /// </summary>
    class IPv6RouterSolicitationHeaeder : IPv6ICMPHeader
    {
        #region infomation
        /*
                     4.1.  Router Solicitation Message Format

               Hosts send Router Solicitations in order to prompt routers to
               generate Router Advertisements quickly.

                  0                   1                   2                   3
                  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                 |     Type      |     Code      |          Checksum             |
                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                 |                            Reserved                           |
                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                 |   Options ...
                 +-+-+-+-+-+-+-+-+-+-+-+-

               IP Fields:

                  Source Address
                                 An IP address assigned to the sending interface, or
                                 the unspecified address if no address is assigned
                                 to the sending interface.

                  Destination Address
                                 Typically the all-routers multicast address.

                  Hop Limit      255




            Narten, et al.              Standards Track                    [Page 18]
 
            RFC 4861               Neighbor Discovery in IPv6         September 2007


               ICMP Fields:

                  Type           133

                  Code           0

                  Checksum       The ICMP checksum.  See [ICMPv6].

                  Reserved       This field is unused.  It MUST be initialized to
                                 zero by the sender and MUST be ignored by the
                                 receiver.
               Valid Options:

                  Source link-layer address The link-layer address of the sender, if
                                 known.  MUST NOT be included if the Source Address
                                 is the unspecified address.  Otherwise, it SHOULD
                                 be included on link layers that have addresses.

                  Future versions of this protocol may define new option types.
                  Receivers MUST silently ignore any options they do not recognize
                  and continue processing the message.

            4.2.  Router Advertisement Message Format

               Routers send out Router Advertisement messages periodically, or in
               response to Router Solicitations.

                  0                   1                   2                   3
                  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                 |     Type      |     Code      |          Checksum             |
                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                 | Cur Hop Limit |M|O|  Reserved |       Router Lifetime         |
                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                 |                         Reachable Time                        |
                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                 |                          Retrans Timer                        |
                 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                 |   Options ...
                 +-+-+-+-+-+-+-+-+-+-+-+-

               IP Fields:

                  Source Address
                                 MUST be the link-local address assigned to the
                                 interface from which this message is sent.





            Narten, et al.              Standards Track                    [Page 19]
 
            RFC 4861               Neighbor Discovery in IPv6         September 2007


                  Destination Address
                                 Typically the Source Address of an invoking Router
                                 Solicitation or the all-nodes multicast address.

                  Hop Limit      255
         */
        #endregion

    }

    /// <summary>
    /// 路由通告报文头   icmp type = 134
    /// </summary>
    public  class IPv6RouterAdvertisementHeader:IPv6ICMPHeader {

        #region infomation 
                /*
                 *
                          4.2.  Router Advertisement Message Format

                      Routers send out Router Advertisement messages periodically, or in
                      response to Router Solicitations.

                         0                   1                   2                   3
                         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                        |     Type      |     Code      |          Checksum             |
                        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                        | Cur Hop Limit |M|O|  Reserved |       Router Lifetime         |
                        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                        |                         Reachable Time                        |
                        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                        |                          Retrans Timer                        |
                        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                        |   Options ...
                        +-+-+-+-+-+-+-+-+-+-+-+-

                      IP Fields:

                         Source Address
                                        MUST be the link-local address assigned to the
                                        interface from which this message is sent.
                 */
        #endregion



        public byte CurHopLimit { get { return message[0]; } set { message[0] = value; } }
        public byte M
        {
            get { return BitGet(message, 8); }
            set { BitSet(message, 8, value); }  
        }
        public byte O
        {
            get { return BitGet(message, 9); }
            set { BitSet(message, 9, value); }
        }
        public UInt16 RouteLifeTime { get { return UInt16Get(message, 2); } set { UInt16Set(message, 2, value); } }
        public UInt32 ReachableTime { get { return UInt32Get(message, 4); } set { UInt32Set(message, 4, value); } }
        public UInt32 RetransTimer { get { return UInt32Get(message, 8); } set { UInt32Set(message, 8, value); } }

        /// <summary>
        /// 可选字节
        /// </summary>
        public byte[] options
        {
            
            set
            {
                int o = 12;
                if (value != null && value.Length > 0)
                {
                    byte[] pre = new byte[o];
                    Array.Copy(message, 0, pre, 0, o);
                    message = new byte[o + value.Length];
                    Array.Copy(value, 0, message, o, value.Length);
                    Array.Copy(pre, 0, message, 0, o);
                }
            }
            get
            {
                int o = 12;
                if (message.Length <= o) return null;
                byte[] v = new byte[message.Length - o];
                Array.Copy(message, o, v, 0, message.Length - o);
                return v;
            }
        }

        public IPv6RouterAdvertisementHeader() { }
        public IPv6RouterAdvertisementHeader(byte[] ipdata, int offset):base(ipdata,offset){}

    }

    /// <summary>
    /// 邻居请求报文头 icmp type = 135
    /// </summary>
    public class IPv6NeighborSolicitationHeader:IPv6ICMPHeader{
    
        #region infomation
                /*
         
                    Nodes send Neighbor Solicitations to request the link-layer address
           of a target node while also providing their own link-layer address to
           the target.  Neighbor Solicitations are multicast when the node needs
           to resolve an address and unicast when the node seeks to verify the
           reachability of a neighbor.

              0                   1                   2                   3
              0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |     Type      |     Code      |          Checksum             |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |                           Reserved                            |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |                                                               |
             +                                                               +
             |                                                               |
             +                       Target Address                          +
             |                                                               |
             +                                                               +
             |                                                               |
             +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |   Options ...
             +-+-+-+-+-+-+-+-+-+-+-+-

            IP Fields:

              Source Address
                             Either an address assigned to the interface from
                             which this message is sent or (if Duplicate Address
                             Detection is in progress [ADDRCONF]) the
                             unspecified address.
              Destination Address
                             Either the solicited-node multicast address
                             corresponding to the target address, or the target
                             address.
              Hop Limit      255

           ICMP Fields:

              Type           135

              Code           0
                 */

        #endregion


        public byte[] Reserved {
            get { byte[] r = new byte[4]; Array.Copy(message, 0, r, 0, 4); return r; }
            set { Array.Copy(value, 0, message, 0, 4); }
        }

        /// <summary>
        /// 目标地址
        /// </summary>
        public byte[] TargetAddress{
            set{
                 byte[] v = (byte[])value;
                Array.Copy(v,0,message,4,16);
            }
            get{
                byte[] v = new byte[16];
                Array.Copy(message,4,v,0,16);
                return v;
            }
        }

        /// <summary>
        /// 可选字节
        /// </summary>
        public IPv6ICMPOption options{
            set{
                if(value !=null ){
                    byte[] pre = new byte[20+value.data.Length];
                    Array.Copy(message,0,pre,0,20);
                    Array.Copy(value.data,0,pre,20,value.data.Length);
                    message = pre;
                }
            }
            get{
                return new IPv6ICMPOption(message, 20);
            }
        }

        public IPv6NeighborSolicitationHeader(){}
        public IPv6NeighborSolicitationHeader(byte[] ipdata,int offset):base(ipdata,offset){}            
        }
    

    /// <summary>
    /// 邻居通告报文头  icmp type = 136
    /// </summary>
    public class IPv6NeighborAdvertisementHeader:IPv6ICMPHeader{
            #region information
                    /*
                        Neighbor Advertisement
                        * 
                                    *    A node sends Neighbor Advertisements in response to Neighbor
                            Solicitations and sends unsolicited Neighbor Advertisements in order
                            to (unreliably) propagate new information quickly.

                                0                   1                   2                   3
                                0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                |     Type      |     Code      |          Checksum             |
                                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                |R|S|O|                     Reserved                            |
                                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                |                                                               |
                                +                                                               +
                                |                                                               |
                                +                       Target Address                          +
                                |                                                               |
                                +                                                               +
                                |                                                               |
                                +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                                |   Options ...
                                +-+-+-+-+-+-+-+-+-+-+-+-





                        Narten, et al.              Standards Track                    [Page 23]
 
                        RFC 4861               Neighbor Discovery in IPv6         September 2007


                            IP Fields:

                                Source Address
                                                An address assigned to the interface from which the
                                                advertisement is sent.
                                Destination Address
                                                For solicited advertisements, the Source Address of
                                                an invoking Neighbor Solicitation or, if the
                                                solicitation's Source Address is the unspecified
                                                address, the all-nodes multicast address.

                                                For unsolicited advertisements typically the all-
                                                nodes multicast address.

                                Hop Limit      255

                            ICMP Fields:

                                Type           136

                                Code           0
         
                        */
            #endregion

            public byte RouterFlag{
                get { return BitGet(message, 0); }
                set { BitSet(message, 0, value); }
            }

            public byte SolicitedFlag{
                get { return BitGet(message, 1); }
                set { BitSet(message,1, value); }   
            }
           
            public byte OverrideFlag{
                get { return BitGet(message, 2); }
                set { BitSet(message, 2, value); }    
            }

            /// <summary>
            /// 目标地址
            /// </summary>
            public byte[] TargetAddress{
                set{
                        byte[] v = (byte[])value;
                    Array.Copy(v,0,message,4,16);
                }
                get{
                    byte[] v = new byte[16];
                    Array.Copy(message,4,v,0,16);
                    return v;
                }
            }
            /// <summary>
            /// 可选字节
            /// </summary>
            public IPv6ICMPOption options
            {
                set
                {
                    if (value != null)
                    {
                        byte[] pre = new byte[20 + value.data.Length];
                        Array.Copy(message, 0, pre, 0, 20);
                        Array.Copy(value.data, 0, pre, 20, value.data.Length);
                        message = pre;
                    }
                }
                get
                {
                    return new IPv6ICMPOption(message, 20);
                }
            }
            
            
            public IPv6NeighborAdvertisementHeader(){}
             
            public IPv6NeighborAdvertisementHeader(byte[] ipdata,int offset):base(ipdata,offset){}
    }
    

    /// <summary>
    /// ipv6 数据包
    /// </summary>
    class IPv6Packet
    {
        /*      _______________________________________________________
         *     | dest mac |  src mac  |  hardtype == 0x86dd | payload  |
         *     |_6btyes___|___6bytes__|_____2bytes__________|____n___ _|
         *
         *      ICMPv6 数据包规则:    
         */

        /*    link layer   */
        //byte[] _dmac = new byte[6];
        //byte[] _smac = new byte[6];
        //HardType type = HardType.IPv6;
        byte[] _linkpayload;
        int _linkpayloadlen;

        /*    IP layer    */


        #region 构造

        /// <summary>
        /// 以IP包 : ip header + payload 创建一个ipv6 pakcet
        /// </summary>
        /// <param name="lldata"></param>
        /// <param name="ipdatalen"></param>
        public IPv6Packet(byte[] lldata, int ipdatalen)
        {
            _linkpayload = new byte[ipdatalen];         
            if(lldata == null)_linkpayloadlen = 0;
            if (ipdatalen < lldata.Length)
            {
                _linkpayloadlen = lldata.Length;
            }
            else _linkpayloadlen = lldata.Length;
            Array.Copy(lldata, 0, _linkpayload, 0, _linkpayloadlen);
        }


        /// <summary>
        /// 创建一个空包
        /// </summary>
        public IPv6Packet() { }

        public IPv6Packet(int buffersize) { this._linkpayload = new byte[buffersize]; this._linkpayloadlen = buffersize; }

        public IPv6Packet(byte[] IPData) {
            _linkpayload = new byte[IPData.Length + 14];
            Array.Copy(IPData, 0, _linkpayload, 14, IPData.Length);
            _linkpayloadlen = _linkpayload.Length;
        }


        /// <summary>
        /// 源mac
        /// </summary>
        public byte[] SourceMac {
            get {
                byte[] _smac = new byte[6];
                Array.Copy(_linkpayload,6,_smac,0, 6);
                return _smac;
            }
            set {
            byte[] b = value;
            Array.Copy(b, 0,_linkpayload, 6,6);
        } }


        /// <summary>
        /// 目标mac
        /// </summary>
        public byte[] DestMac {
            get {
                byte[] _dmac = new byte[6];
                Array.Copy(_linkpayload, 0, _dmac, 0, 6);
                return _dmac;
            }
            set {
                Array.Copy(value, 0, _linkpayload, 0, 6);
            }
        }


        /// <summary>
        /// 硬件类型
        /// </summary>
        public HardType hardType {
            set {
                _linkpayload[12] = (byte)((UInt16)value >> 8);
                _linkpayload[13] = (byte)((UInt16)value & 0xFF);
            }
            get {
                UInt16 v = _linkpayload[12]; v <<= 8; v += _linkpayload[13];
                return (HardType)v;
            }
        }


        /// <summary>
        /// IP数据段
        /// </summary>
        public byte[] IPPayload {
            get {
                if (_linkpayloadlen < 14) return null;
                byte[] _p = new byte[_linkpayloadlen-14];
                Array.Copy(_linkpayload, 14, _p, 0, _linkpayloadlen - 14);
                return _p;
            }
        }

        public byte[] PacketData { get { return _linkpayload; } }

        /// <summary>
        /// 以属性访问 header
        /// </summary>
        public IPv6Header IPv6header {
            set { 
                Array.Copy(value.HeaderData, 0,_linkpayload, 14,  IPv6Header.HeaderSize); 
            }
            get { return IPv6Header.Parse(this._linkpayload, 14); }
        }


        public IPv6ICMPHeader Ipv6icmpHeader {
            get { return this.ToIPv6ICMPHeader(); }
            set {
                    byte[] pre = new byte[14 + IPv6Header.HeaderSize + value.icmpdata.Length];
                    Array.Copy(_linkpayload, 0, pre, 0, 14 + IPv6Header.HeaderSize);
                    Array.Copy(value.icmpdata, 0, pre, 14 + IPv6Header.HeaderSize, value.icmpdata.Length);
                    _linkpayload = pre;
                    _linkpayloadlen = pre.Length;

                    //ip payload len == icmpheaer.size( header + data) ,while hotop ,this value  =0
                    IPv6Header iph = this.IPv6header;
                    iph.PayloadLength =(UInt16) value.icmpdata.Length;
                    if (iph.NextHeader == IPv6NextHeaderType.HOPOPT) iph.PayloadLength = 0;
                    this.IPv6header = iph;
                }
        }

        public IPv6NeighborSolicitationHeader Ipv6NSheader {
            get { return new IPv6NeighborSolicitationHeader(this.Ipv6icmpHeader.icmpdata, 0); }
            set { this.Ipv6icmpHeader = value; }
        }
        public IPv6NeighborAdvertisementHeader Ipv6NAheader {
            get { return new IPv6NeighborAdvertisementHeader(this.Ipv6icmpHeader.icmpdata, 0); }
            set { this.Ipv6icmpHeader = value; }
        }


        /// <summary>
        /// 取得ip 头
        /// </summary>
        /// <returns></returns>
        public IPv6Header ToIPv6Header() {
            try {return IPv6Header.Parse(this.IPPayload,0);}catch { return null; }
        }

        /// <summary>
        /// 取得icmpv6 头
        /// </summary>
        /// <returns></returns>
        public IPv6ICMPHeader ToIPv6ICMPHeader() {
            IPv6Header iheader = this.ToIPv6Header();
            if (iheader.NextHeader == IPv6NextHeaderType.IPv6_ICMP) {
                return IPv6ICMPHeader.Parse(this.IPPayload, IPv6Header.HeaderSize);
            } return null;
        }



        /// <summary>
        /// 反回icmpv6 伪头
        /// </summary>
        /// <returns></returns>
        public IPv6ICMPPseudoHeader toIPv6ICMPPseudoHeader() {
            IPv6Header iph = this.ToIPv6Header();
            if (iph != null)
            {
                IPv6ICMPPseudoHeader ipph = new IPv6ICMPPseudoHeader();
                Array.Copy(iph.SourceAddress, ipph.SourceAddress, 16);
                Array.Copy(iph.DestnationAddress, ipph.DestationAddress, 16);
                ///Len 为 IP 包中的 len 长度
                ipph.PayloadLen = iph.PayloadLength;
                ipph.next = iph.NextHeader;

                //icmp data
                ipph.icmpv6data = this.Ipv6icmpHeader.icmpdata;
                return ipph;
            }
            else return null;
        }


        #endregion

        static String Endline { get { return "\r\n"; } }
        static String Space { get { return " "; } }
        public String HeaderInfor()
        {
            IPv6Header header = this.ToIPv6Header();
            String str="";
            try
            {
                str += System.DateTime.Now.ToString("[hh:mm:ss]") + this._linkpayloadlen + "-------------------------------"+ Endline;
                str += "Smac:" + Ulitily.ShareClass.hexByteArrayToString(this.SourceMac).Replace("-", ":") + Endline
                + "Dmac:" + Ulitily.ShareClass.hexByteArrayToString(this.DestMac).Replace("-", ":") + Endline
                + "Hardtype:" + this.hardType.ToString() + Endline;

            if (this.hardType != HardType.IPv6) {
                    return str + "payload:"+ Ulitily.ShareClass.hexByteArrayToString(_linkpayload, 14, _linkpayload.Length - 14).Replace("-"," ") +Endline;
            }else str = str 
            + "srcAddress:" + Ulitily.ShareClass.hexByteArrayToString(header.SourceAddress).Replace("-", ":") + Endline
            + "destAddress:" + Ulitily.ShareClass.hexByteArrayToString(header.DestnationAddress).Replace("-", ":") + Endline
            + "flowlabel:" + header.FlowLabel + Endline
            + "hop limit" + header.HopLimit + Endline
            + "next header:" + header.NextHeader + Endline+ Endline;

            }
            catch { }
            return str;
        }

        public String icmpInfor {
            get {

                try {
                    string s = "";
                    if (IPv6header.NextHeader == IPv6NextHeaderType.IPv6_ICMP) {
                        IPv6ICMPHeader ih = this.Ipv6icmpHeader;
                        s += "icmp type:" + ih.type.ToString() + Endline
                            + "icmp code:" + ih.code + Endline
                            + "check sum:" + ih.checksum.ToString() + Endline;

                            switch (ih.type) { 
                                case ICMPv6Type.Neighbor_Solicitation_NDP:
                                    IPv6NeighborSolicitationHeader ns = this.Ipv6NSheader;
                                    s += "NS option type:" + ns.options.type + Endline
                                        + "NS option len:" + ns.options.optionLen + Endline
                                        + "NS option Data:" + Ulitily.ShareClass.hexByteArrayToString(ns.options.optionData).Replace("-", " ") + Endline;

                                    break;
                                case ICMPv6Type.Neighbor_Advertisement_NDP:
                                    IPv6NeighborAdvertisementHeader na = this.Ipv6NAheader;
                                    s += "NA option type:" + na.options.type + Endline
                                        + "NA option len:" + na.options.optionLen + Endline
                                        + "NA option Data:" + Ulitily.ShareClass.hexByteArrayToString(na.options.optionData).Replace("-", " ") + Endline;
                                    break;

                                case ICMPv6Type.Echo_Request:
                                case ICMPv6Type.Echo_Reply:
                                    Echorequest er = new Echorequest(ih.icmpdata, 0, ih.icmpdata.Length);
                                    s += "identifier" + er.Identifier + Endline
                                        + "sequence number:" + er.SequenceNumber + Endline
                                        + "data:" + System.Text.Encoding.Default.GetString(er.Data,0,er.Data.Length)+ Endline;
                                    break;

                                default:
                                    if (ih.message.Length > 0)
                                    {
                                        s += "message:" + Ulitily.ShareClass.hexByteArrayToString(ih.message).Replace("-", " ")
                                            + Endline + Endline;
                                    }break;

                            }



                        return s;
                    }
                }
                catch { return null; }

                return null;
            }
        }

    }
}
